const { PrismaClient } = require('@prisma/client')
const prisma = new PrismaClient()
const fs = require('fs')
const path = require('path')
const { exec } = require('child_process')
const util = require('util')
const execPromise = util.promisify(exec)


// 存储备份文件的目录
const BACKUPS_DIR = path.join(__dirname, '../../uploads/backups')

// 确保备份目录存在
if (!fs.existsSync(BACKUPS_DIR)) {
  fs.mkdirSync(BACKUPS_DIR, { recursive: true })
}

// 数据库连接配置
const DB_CONFIG = {
  host: process.env.DB_HOST || 'hello-beer-db',
  port: process.env.DB_PORT || 3306,
  user: process.env.DB_USER || 'root',
  password: process.env.DB_PASSWORD || 'Hello_Beer_2023',
  database: process.env.DB_NAME || 'hello_beer'
}

/**
 * 生成数据库备份
 */
exports.backupDatabase = async (req, res) => {
  try {
    console.log('开始生成数据库备份...')

    // 生成备份文件名
    const timestamp = new Date().toISOString().replace(/[:.]/g, '-')
    const backupFileName = `backup-${timestamp}.sql`
    const backupFilePath = path.join(BACKUPS_DIR, backupFileName)

    // 构建备份命令（优先使用mariadb-dump，回退到mysqldump）
    const baseOptions = `-h ${DB_CONFIG.host} -P ${DB_CONFIG.port} -u ${DB_CONFIG.user} -p${DB_CONFIG.password} --single-transaction --routines --triggers --skip-ssl --skip-ssl-verify-server-cert ${DB_CONFIG.database}`

    console.log('执行备份命令...')

    // 尝试使用 mariadb-dump
    try {
      const mariadbDumpCmd = `mariadb-dump ${baseOptions} > ${backupFilePath}`
      await execPromise(mariadbDumpCmd)
      console.log('使用 mariadb-dump 备份成功')
    } catch (mariadbError) {
      console.log('mariadb-dump 失败，尝试使用 mysqldump...')
      // 回退到 mysqldump
      const mysqldumpCmd = `mysqldump ${baseOptions} > ${backupFilePath}`
      await execPromise(mysqldumpCmd)
      console.log('使用 mysqldump 备份成功')
    }

    // 检查备份文件是否生成成功
    if (!fs.existsSync(backupFilePath)) {
      throw new Error('备份文件生成失败')
    }

    const stats = fs.statSync(backupFilePath)
    console.log(`备份完成，文件大小: ${(stats.size / 1024 / 1024).toFixed(2)} MB`)



    // 返回下载链接
    res.json({
      status: 'success',
      message: '数据库备份生成成功',
      data: {
        fileName: backupFileName,
        fileSize: stats.size,
        downloadUrl: `/api/migration/download/${backupFileName}`
      }
    })

  } catch (error) {
    console.error('生成数据库备份失败:', error)
    res.status(500).json({
      status: 'error',
      message: '生成数据库备份失败',
      error: error.message
    })
  }
}

/**
 * 恢复数据库
 */
exports.restoreDatabase = async (req, res) => {
  try {
    const file = req.file
    if (!file) {
      return res.status(400).json({
        status: 'error',
        message: '未上传备份文件'
      })
    }

    console.log('开始恢复数据库...')
    console.log('备份文件:', file.originalname, '大小:', file.size)

    // 验证文件格式
    if (!file.originalname.endsWith('.sql')) {
      return res.status(400).json({
        status: 'error',
        message: '只支持.sql格式的备份文件'
      })
    }

    // 构建恢复命令（优先使用mariadb，回退到mysql）
    const baseOptions = `-h ${DB_CONFIG.host} -P ${DB_CONFIG.port} -u ${DB_CONFIG.user} -p${DB_CONFIG.password} --skip-ssl --skip-ssl-verify-server-cert ${DB_CONFIG.database}`

    console.log('执行恢复命令...')

    // 尝试使用 mariadb
    try {
      const mariadbCmd = `mariadb ${baseOptions} < ${file.path}`
      await execPromise(mariadbCmd)
      console.log('使用 mariadb 恢复成功')
    } catch (mariadbError) {
      console.log('mariadb 失败，尝试使用 mysql...')
      // 回退到 mysql
      const mysqlCmd = `mysql ${baseOptions} < ${file.path}`
      await execPromise(mysqlCmd)
      console.log('使用 mysql 恢复成功')
    }

    console.log('数据库恢复完成')

    // 删除临时文件
    fs.unlinkSync(file.path)



    res.json({
      status: 'success',
      message: '数据库恢复成功',
      data: {
        fileName: file.originalname,
        fileSize: file.size
      }
    })

  } catch (error) {
    console.error('恢复数据库失败:', error)

    // 删除临时文件
    if (req.file && req.file.path) {
      try {
        fs.unlinkSync(req.file.path)
      } catch (e) {
        console.error('删除临时文件失败:', e)
      }
    }

    res.status(500).json({
      status: 'error',
      message: '恢复数据库失败',
      error: error.message
    })
  }
}

/**
 * 下载备份文件
 */
exports.downloadBackup = async (req, res) => {
  try {
    const { fileName } = req.params
    const filePath = path.join(BACKUPS_DIR, fileName)

    // 检查文件是否存在
    if (!fs.existsSync(filePath)) {
      return res.status(404).json({
        status: 'error',
        message: '备份文件不存在'
      })
    }

    // 设置下载头
    res.setHeader('Content-Disposition', `attachment; filename="${fileName}"`)
    res.setHeader('Content-Type', 'application/sql')

    // 发送文件
    res.sendFile(filePath)

  } catch (error) {
    console.error('下载备份文件失败:', error)
    res.status(500).json({
      status: 'error',
      message: '下载备份文件失败',
      error: error.message
    })
  }
}

/**
 * 获取备份历史
 */
exports.getBackupHistory = async (req, res) => {
  try {
    const backupFiles = []

    console.log('备份目录路径:', BACKUPS_DIR)
    console.log('备份目录是否存在:', fs.existsSync(BACKUPS_DIR))

    // 读取备份目录
    if (fs.existsSync(BACKUPS_DIR)) {
      const files = fs.readdirSync(BACKUPS_DIR)
      console.log('备份目录中的文件:', files)

      for (const file of files) {
        if (file.endsWith('.sql')) {
          const filePath = path.join(BACKUPS_DIR, file)
          const stats = fs.statSync(filePath)

          backupFiles.push({
            fileName: file,
            fileSize: stats.size,
            createdAt: stats.birthtime,
            downloadUrl: `/api/migration/download/${file}`
          })
        }
      }
    }

    // 按创建时间倒序排列
    backupFiles.sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt))

    res.json({
      status: 'success',
      data: backupFiles
    })

  } catch (error) {
    console.error('获取备份历史失败:', error)
    res.status(500).json({
      status: 'error',
      message: '获取备份历史失败',
      error: error.message
    })
  }
}

/**
 * 删除备份文件
 */
exports.deleteBackup = async (req, res) => {
  try {
    const { fileName } = req.params
    const filePath = path.join(BACKUPS_DIR, fileName)

    // 检查文件是否存在
    if (!fs.existsSync(filePath)) {
      return res.status(404).json({
        status: 'error',
        message: '备份文件不存在'
      })
    }

    // 删除文件
    fs.unlinkSync(filePath)



    res.json({
      status: 'success',
      message: '备份文件删除成功'
    })

  } catch (error) {
    console.error('删除备份文件失败:', error)
    res.status(500).json({
      status: 'error',
      message: '删除备份文件失败',
      error: error.message
    })
  }
}